package servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.dialect.Dialect;
import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean;
import org.springframework.orm.toplink.LocalSessionFactoryBean;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundOperation.ANONYMOUS;

import entity.Test;

/**
 * @author Paulo Sobreira [sowbreira@gmail.com]
 * @author Rafael Carneiro [rafaelcarneirob@gmail.com]
 */
public class HibernateServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		PrintWriter printWriter = response.getWriter();
		try {
			printWriter.println("<html><body>");

			ApplicationContext context = WebApplicationContextUtils
					.getWebApplicationContext(getServletContext());

			SessionFactory sessionFactory = (SessionFactory) context
					.getBean("sessionFactory");

			AnnotationSessionFactoryBean annotationSessionFactoryBean = (AnnotationSessionFactoryBean) context
					.getBean("&sessionFactory");

			AnnotationConfiguration cfg = (AnnotationConfiguration) annotationSessionFactoryBean
					.getConfiguration();

			String param = request.getParameter("act");

			if ("create_schema".equals(param)) {
				createSchema(cfg, sessionFactory, printWriter);
			} else if ("update_schema".equals(param)) {
				updateSchema(cfg, sessionFactory, printWriter);
			} else if ("insert_data".equals(param)) {
				insert(sessionFactory);
			} else if ("list_data".equals(param)) {
				list(sessionFactory, printWriter);
			}

			printWriter.println("<br/> " + param + " done");
		} catch (Exception e) {
			printWriter.println(e.getMessage());
		}
		printWriter.println("<br/><a href='index.jsp'>back</a>");
		printWriter.println("</body></html>");
		response.flushBuffer();
	}

	private void list(SessionFactory sessionFactory, PrintWriter printWriter) {
		Session session = sessionFactory.openSession();
		Criteria criteria = session.createCriteria(Test.class);
		List<Test> listOfTests = criteria.list();

		for (Test test : listOfTests) {
			printWriter.println("<br/> " + test);
		}

	}

	private void updateSchema(AnnotationConfiguration cfg,
			SessionFactory sessionFactory, PrintWriter printWriter)
			throws SQLException {
		Dialect dialect = Dialect.getDialect(cfg.getProperties());
		Session session = sessionFactory.openSession();
		DatabaseMetadata meta = new DatabaseMetadata(session.connection(),
				dialect);
		String[] strings = cfg.generateSchemaUpdateScript(dialect, meta);
		executeStatement(sessionFactory, strings, printWriter);

	}

	private void executeStatement(SessionFactory sessionFactory,
			String[] strings, PrintWriter printWriter) throws SQLException {

		Session session = sessionFactory.openSession();
		session.beginTransaction();

		for (int i = 0; i < strings.length; i++) {
			String string = strings[i];
			java.sql.Statement statement = session.connection()
					.createStatement();
			statement.execute(string);
			printWriter.println("<br/> " + string);
		}

		session.flush();

	}

	private void insert(SessionFactory sessionFactory) {
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		session.saveOrUpdate(new Test("Hibernate OK " + new Date()));
		session.flush();
	}

	private void createSchema(AnnotationConfiguration cfg,
			SessionFactory sessionFactory, PrintWriter printWriter)
			throws HibernateException, SQLException {
		Dialect dialect = Dialect.getDialect(cfg.getProperties());
		String[] strings = cfg.generateSchemaCreationScript(dialect);
		executeStatement(sessionFactory, strings, printWriter);
	}
}
